package org.jeecg.modules.demo.oa.service.impl;


import com.aliyun.oss.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.dto.message.TemplateMessageDTO;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.demo.oa.entity.ComApprovalList;
import org.jeecg.modules.demo.oa.entity.ComApprovalListLog;
import org.jeecg.modules.demo.oa.entity.OaHetong;
import org.jeecg.modules.demo.oa.entity.OaHetongShenpi;
import org.jeecg.modules.demo.oa.mapper.OaHetongShenpiMapper;
import org.jeecg.modules.demo.oa.mapper.OaHetongMapper;
import org.jeecg.modules.demo.oa.service.IComApprovalListLogService;
import org.jeecg.modules.demo.oa.service.IComApprovalListService;
import org.jeecg.modules.demo.oa.service.IOaHetongService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Stream;

/**
 * @Description: 合同审批表
 * @Author: jeecg-boot
 * @Date:   2024-09-11
 * @Version: V1.0
 */
@Service
public class OaHetongServiceImpl extends ServiceImpl<OaHetongMapper, OaHetong> implements IOaHetongService {

	@Autowired
	private OaHetongMapper oaHetongMapper;
	@Autowired
	private OaHetongShenpiMapper oaHetongShenpiMapper;

	@Autowired
	private IComApprovalListService comApprovalListService;

	@Autowired
	private IComApprovalListLogService comApprovalListLogService;

	@Autowired
	private ISysBaseAPI sysBaseAPI;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveMain(OaHetong oaHetong, List<OaHetongShenpi> oaHetongShenpiList) {
		oaHetongMapper.insert(oaHetong);
		if(oaHetongShenpiList!=null && oaHetongShenpiList.size()>0) {
			for(OaHetongShenpi entity:oaHetongShenpiList) {
				//外键设置
				entity.setHetongId(oaHetong.getId());
				oaHetongShenpiMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateMain(OaHetong oaHetong,List<OaHetongShenpi> oaHetongShenpiList) {
		oaHetongMapper.updateById(oaHetong);
		
		//1.先删除子表数据
		oaHetongShenpiMapper.deleteByMainId(oaHetong.getId());
		
		//2.子表数据重新插入
		if(oaHetongShenpiList!=null && oaHetongShenpiList.size()>0) {
			for(OaHetongShenpi entity:oaHetongShenpiList) {
				//外键设置
				entity.setHetongId(oaHetong.getId());
				oaHetongShenpiMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delMain(String id) {
		oaHetongShenpiMapper.deleteByMainId(id);
		oaHetongMapper.deleteById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			oaHetongShenpiMapper.deleteByMainId(id.toString());
			oaHetongMapper.deleteById(id);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void tijiao(List<String> list) {
		list.forEach(id->{
			OaHetong oaHetong = oaHetongMapper.selectById(id);
			List<OaHetongShenpi> oaHetongShenpiList = oaHetongShenpiMapper.selectByMainId(oaHetong.getId());

			Assert.isTrue(! oaHetongShenpiList.isEmpty(),"请先添加审批节点");
			Integer jiedianOrdinal = oaHetongShenpiList.get(0).getJiedianOrdinal();

			String billNo = oaHetong.getHetongNo();
			String billName = oaHetong.getHetongName();
			String shenqinBy = oaHetong.getCreateBy();
			Date shenqinTime = oaHetong.getCreateTime();
			String remark = oaHetong.getRemark();
			String billStatus = oaHetong.getBillStatus();
			if( billStatus.equals("1") || billStatus.equals("0") ){
				oaHetong.setBillStatus("2");

				String resultColName = "sign_result";
				String yijianColName = "sign_yijian";
				String timeColName = "sign_time";
				String billType = "合同申请首次审批";

				oaHetongShenpiList.forEach(oaHetongShenpi->{
					if ( oaHetongShenpi.getJiedianOrdinal().equals(jiedianOrdinal)){
						oaHetongShenpi.setSignResult("待审批");

						//添加到待审批列表
						addApproval(oaHetongShenpi, oaHetong, resultColName,yijianColName, timeColName,billType,false);

						//发送消息和邮件
						String jiedianLeader = oaHetongShenpi.getJiedianLeader();

						//给审批人发送审批消息
						sendShenPiMsg(billType, billNo, billName, shenqinBy, shenqinTime, remark, jiedianLeader);

					}
					else {
						oaHetongShenpi.setSignResult("未审批");
					}

					oaHetongShenpi.setSignTime(null);
					oaHetongShenpi.setSignYijian("");
					oaHetongShenpiMapper.updateById(oaHetongShenpi);



				});

			}
			else if ( billStatus.equals("3")){
				oaHetong.setBillStatus("4");

				String resultColName = "sign_result2";
				String yijianColName = "sign_yijian2";
				String timeColName = "sign_time2";
				String billType = "合同申请二次审批";

				oaHetongShenpiList.forEach(oaHetongShenpi->{
					if ( oaHetongShenpi.getJiedianOrdinal().equals(jiedianOrdinal)){
						oaHetongShenpi.setSignResult2("待审批");

						//添加到待审批列表
						addApproval(oaHetongShenpi, oaHetong, resultColName,yijianColName, timeColName,billType,false);

						//发送消息和邮件
						String jiedianLeader = oaHetongShenpi.getJiedianLeader();

						//给审批人发送审批消息
						sendShenPiMsg(billType, billNo, billName, shenqinBy, shenqinTime, remark, jiedianLeader);

					}
					else {
						oaHetongShenpi.setSignResult2("未审批");
					}

					oaHetongShenpi.setSignTime2(null);
					oaHetongShenpi.setSignYijian2("");
					oaHetongShenpiMapper.updateById(oaHetongShenpi);
				});

			}

			oaHetong.setShenpiOrdinal(jiedianOrdinal);
			oaHetongMapper.updateById(oaHetong);


		});


	}

	/**
	 * 发送消息
	 * @param billType
	 * @param billNo
	 * @param billName
	 * @param shenqinBy
	 * @param shenqinTime
	 * @param remark
	 * @param jiedianLeader
	 */
	private void sendShenPiMsg(String billType, String billNo, String billName, String shenqinBy, Date shenqinTime, String remark, String jiedianLeader) {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String shenqinTimeStr = sdf.format(shenqinTime);

		Map<String, String> map = new HashMap<>();
		map.put("billType", billType);
		map.put("billNo", billNo);
		map.put("billName", billName) ;
		map.put("shenQinRen", shenqinBy);
		map.put("shenQinTime", shenqinTimeStr);
		map.put("remark", remark);

		TemplateMessageDTO messageDTO = new TemplateMessageDTO();
		messageDTO.setFromUser(shenqinBy);
		messageDTO.setToUser(jiedianLeader);
		messageDTO.setTemplateCode("oa_bill_shenpi");
		messageDTO.setTemplateParam(map);
		sysBaseAPI.sendTemplateAnnouncement(messageDTO);
	}


	private void addApproval(OaHetongShenpi oaHetongShenpi, OaHetong oaHetong,	String resultColName,
							 String yijianColName, String timeColName, String billType ,Boolean isLog)    {
		String hetongNo = oaHetong.getHetongNo();

		if( isLog.equals(false)){
			ComApprovalList comApprovalList = new ComApprovalList();
			comApprovalList.setBillName(oaHetong.getHetongName());
			comApprovalList.setBillType(billType ) ;
			comApprovalList.setBillNo(hetongNo) ;
			comApprovalList.setDetailUrl("/oa/hetong/detail?shenpi_id="+ oaHetong.getId());
			comApprovalList.setJiedianName(oaHetongShenpi.getJiedianName());
			comApprovalList.setJiedianOrdinal(oaHetongShenpi.getJiedianOrdinal());
			comApprovalList.setTableName("oa_hetong_shenpi");
			comApprovalList.setTableRecordId(oaHetongShenpi.getId());
			comApprovalList.setResultColName(resultColName);
			comApprovalList.setYijianColName(yijianColName);
			comApprovalList.setTimeColName(timeColName);
			comApprovalList.setLogColName("shenpi_log");
			comApprovalList.setMainIdColName("hetong_id");
			comApprovalList.setShenpiBy(oaHetongShenpi.getJiedianLeader());
			comApprovalList.setSignResult("");
			comApprovalList.setSignYijian("");

			comApprovalList.setShenqinBy( oaHetong.getCreateBy());
			comApprovalList.setShenqinTime(oaHetong.getCreateTime());
			comApprovalList.setRemark("") ;

			comApprovalListService.save(comApprovalList);
		}
		else {

			ComApprovalListLog comApprovalList = new ComApprovalListLog();
			comApprovalList.setBillName(oaHetong.getHetongName());
			comApprovalList.setBillType(billType) ;
			comApprovalList.setBillNo(hetongNo) ;
			comApprovalList.setDetailUrl("/oa/hetong/detail?shenpi_id="+ oaHetong.getId());
			comApprovalList.setJiedianName(oaHetongShenpi.getJiedianName());
			comApprovalList.setJiedianOrdinal(oaHetongShenpi.getJiedianOrdinal());
			comApprovalList.setTableName("oa_hetong_shenpi");
			comApprovalList.setTableRecordId(oaHetongShenpi.getId());
			comApprovalList.setResultColName(resultColName);
			comApprovalList.setYijianColName(yijianColName);
			comApprovalList.setTimeColName(timeColName);
			comApprovalList.setLogColName("shenpi_log");

			comApprovalList.setMainIdColName("hetong_id");

			comApprovalList.setShenpiBy(oaHetongShenpi.getJiedianLeader());

			comApprovalList.setSignResult("");
			comApprovalList.setSignYijian("");

			comApprovalList.setShenqinBy( oaHetong.getCreateBy());
			comApprovalList.setShenqinTime(oaHetong.getCreateTime());
			comApprovalList.setRemark("") ;

			comApprovalListLogService.save(comApprovalList);
		}

	}

	@Override
	public void fanTijiao(List<String> list) {
		list.forEach(id->{
			OaHetong oaHetong = oaHetongMapper.selectById(id);
			List<OaHetongShenpi> oaHetongShenpiList = oaHetongShenpiMapper.selectByMainId(oaHetong.getId());

			if( oaHetongShenpiList.isEmpty()){
				return ;
			}

			if( oaHetong.getBillStatus().equals("2")){
				oaHetong.setBillStatus("1");
				oaHetongShenpiList.forEach(oaHetongShenpi->{
					//清空审批记录
					oaHetongShenpi.setSignResult("未审批");
					oaHetongShenpi.setSignYijian("");
					oaHetongShenpi.setSignTime(null);
					oaHetongShenpiMapper.updateById(oaHetongShenpi);

					deleteApproval(oaHetongShenpi);

				});

			}
			else if ( oaHetong.getBillStatus().equals("4")){
				oaHetong.setBillStatus("3");

				oaHetongShenpiList.forEach(oaHetongShenpi->{
					//清空审批记录
					oaHetongShenpi.setSignResult2("未审批");
					oaHetongShenpi.setSignYijian2("");
					oaHetongShenpi.setSignTime2(null);
					oaHetongShenpiMapper.updateById(oaHetongShenpi);

					deleteApproval(oaHetongShenpi);
				});

			}

			if(! oaHetongShenpiList.isEmpty()){
				oaHetong.setShenpiOrdinal(oaHetongShenpiList.get(0).getJiedianOrdinal());
			}

			oaHetongMapper.updateById(oaHetong);

		});

	}

	private void deleteApproval(OaHetongShenpi oaHetongShenpi) {
		QueryWrapper<ComApprovalList> wrapper = new QueryWrapper<>();
		wrapper.eq("table_name", "oa_hetong_shenpi");
		wrapper.eq("table_record_id", oaHetongShenpi.getId());
		comApprovalListService.remove(wrapper);
	}

	@Override
	public void shenpi(OaHetongShenpi shenpi_old) {
		String hetongId = shenpi_old.getHetongId();
		String id = shenpi_old.getId();

		OaHetong oaHetong = oaHetongMapper.selectById(hetongId);
		OaHetongShenpi shenpi_update = oaHetongShenpiMapper.selectById(id);

		//当单据状态等于2：首次审批中，审批节点通过，进入下一节点
		if( oaHetong.getBillStatus().equals("2")){
			firstShenpi(shenpi_old, shenpi_update, oaHetong);

		}
		//当单据状态等于4：二次审批中，审批节点通过，进入下一节点
		else{
			secondShenpi(shenpi_old, shenpi_update, oaHetong);
		}

	}

	private void secondShenpi(OaHetongShenpi old_shenpi, OaHetongShenpi shenpi_update,  OaHetong oaHetong) {
		String resultColName = "sign_result2";
		String yijianColName = "sign_yijian2";
		String timeColName = "sign_time2";
		String billType="合同申请二次审批";

		LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
		Date dtNow = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dtNowStr = sdf.format(dtNow);

		shenpi_update.setSignTime2(dtNow);
		shenpi_update.setSignResult2( old_shenpi.getSignResult2());
		shenpi_update.setSignYijian2(old_shenpi.getSignYijian2() );

		String shenpiLog = shenpi_update.getShenpiLog();
		if( StringUtils.isNullOrEmpty(shenpiLog) ){
			shenpiLog= sysUser.getUsername()+ "二次审批 "+ dtNowStr + " "+ old_shenpi.getSignResult2()
					+ "("+ old_shenpi.getSignYijian2()+")";
		}
		else {
			shenpiLog=  sysUser.getUsername()+"二次审批 "+ dtNowStr + " " + old_shenpi.getSignResult2()
					+ "("+ old_shenpi.getSignYijian2()+")\n"+ shenpiLog;
		}
		shenpi_update.setShenpiLog(shenpiLog );
		oaHetongShenpiMapper.updateById(shenpi_update);

		//删除当前审批
		deleteApproval(shenpi_update);

		//添加到历史审批记录
		addApproval(shenpi_update, oaHetong, resultColName,yijianColName, timeColName,billType,true);

		List<OaHetongShenpi> oaHetongShenpiList = oaHetongShenpiMapper.selectByMainId(old_shenpi.getHetongId());

		//通过，进入下一节点
		if( shenpi_update.getSignResult2().equals("通过")){
			long count = oaHetongShenpiList.stream()
					.filter(Sp -> Sp.getJiedianOrdinal().equals(shenpi_update.getJiedianOrdinal())
							&& (Sp.getSignResult2() ==null || ! Sp.getSignResult2().equals("通过") )  ).count();

			//没有找到当前节点未审批的记录，则表示该节点全部审批完成，进入下一节点
			if(count == 0){
				int finalOrdinal;
				Optional<OaHetongShenpi> first = oaHetongShenpiList.stream()
						.filter(Sp -> Sp.getJiedianOrdinal() > shenpi_update.getJiedianOrdinal()
						&& (Sp.getSignResult2() == null
						|| !Sp.getSignResult2().equals("通过"))).findFirst();

				if(first.isPresent()){
					finalOrdinal = first.get().getJiedianOrdinal();
				} else {
                    finalOrdinal = -1;
                }

                //审批完成，更新主表状态为审批完成
				if( finalOrdinal<0){
					oaHetong.setUpdateBy(sysUser.getUsername());
					oaHetong.setUpdateTime(dtNow);
					oaHetong.setBillStatus("5"); //5表示二次审批通过
					oaHetongMapper.updateById(oaHetong);
				}
				//审批未完成，更新下一节点状态为待审批
				else {

					Stream<OaHetongShenpi> oaHetongShenpiStream1 = oaHetongShenpiList.stream()
							.filter(Sp -> Sp.getJiedianOrdinal().equals(finalOrdinal));

					oaHetongShenpiStream1.forEach(Sp -> {
						Sp.setSignResult2("待审批");
						Sp.setSignYijian2("");
						Sp.setSignTime2(null);
						oaHetongShenpiMapper.updateById(Sp);

						//添加审批记录
						addApproval(Sp, oaHetong, resultColName,yijianColName, timeColName,billType,false);

					});

					oaHetong.setUpdateBy(sysUser.getUsername());
					oaHetong.setUpdateTime(dtNow);
					oaHetong.setShenpiOrdinal(finalOrdinal);
					oaHetongMapper.updateById(oaHetong);
				}

			}

		}
		//驳回，更新主表状态为驳回
		else {
			// 设置主表审批节点为子表第一个节点
			oaHetong.setShenpiOrdinal( oaHetongShenpiList.get(0).getJiedianOrdinal() );
			// 3表示首次审批通过
			oaHetong.setBillStatus("3");

			oaHetong.setUpdateBy(sysUser.getUsername());
			oaHetong.setUpdateTime(dtNow);
			oaHetongMapper.updateById(oaHetong);

			for(OaHetongShenpi Shenpi : oaHetongShenpiList){
				Shenpi.setSignResult2("");
				Shenpi.setSignYijian2("");
				Shenpi.setSignTime2(null);
				oaHetongShenpiMapper.updateById(Shenpi);

			}

		}



	}

	private void firstShenpi(OaHetongShenpi old_shenpi, OaHetongShenpi shenpi_update,  OaHetong oaHetong) {
		String resultColName = "sign_result";
		String yijianColName = "sign_yijian";
		String timeColName = "sign_time";
		String billType = "合同申请首次审批";

		LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
		Date dtNow = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dtNowStr = sdf.format(dtNow);

		shenpi_update.setSignTime(dtNow);
		shenpi_update.setSignResult( old_shenpi.getSignResult());
		shenpi_update.setSignYijian(old_shenpi.getSignYijian() );

		String shenpiLog = shenpi_update.getShenpiLog();
		if( StringUtils.isNullOrEmpty(shenpiLog) ){
			shenpiLog= sysUser.getUsername()+ "首次审批 "+ dtNowStr + " "  + old_shenpi.getSignResult()
					+ "("+ old_shenpi.getSignYijian()+")";
		}
		else {
			shenpiLog= sysUser.getUsername()+"首次审批 "+ dtNowStr + " " + old_shenpi.getSignResult()
					+ "("+ old_shenpi.getSignYijian()+")\n"+ shenpiLog;
		}
		shenpi_update.setShenpiLog(shenpiLog );

		oaHetongShenpiMapper.updateById(shenpi_update);

		//删除当前审批
		deleteApproval(shenpi_update);

		//添加到历史审批记录
		addApproval(shenpi_update, oaHetong, resultColName,yijianColName, timeColName,billType,true);


		List<OaHetongShenpi> oaHetongShenpiList = oaHetongShenpiMapper.selectByMainId(shenpi_update.getHetongId());
		//通过，进入下一节点
		if( shenpi_update.getSignResult().equals("通过")){
			long count = oaHetongShenpiList.stream()
					.filter(Sp -> Sp.getJiedianOrdinal().equals(shenpi_update.getJiedianOrdinal())
							&& (Sp.getSignResult() ==null || ! Sp.getSignResult().equals("通过") )  ).count();

			//没有找到当前节点未审批的记录，则表示当前节点全部审批完成，则开始审批下一节点
			if(count == 0){
				int finalOrdinal;

				Optional<OaHetongShenpi> first = oaHetongShenpiList.stream().filter(Sp -> Sp.getJiedianOrdinal() > shenpi_update.getJiedianOrdinal()
						&& (Sp.getSignResult() == null
						|| !Sp.getSignResult().equals("通过"))).findFirst();

				if(first.isPresent()){
					finalOrdinal = first.get().getJiedianOrdinal();
				} else {
                    finalOrdinal = -1;
                }

                //所有节点全部审批完成，更新主表状态为审批完成
				if( finalOrdinal<0){
					oaHetong.setUpdateBy(sysUser.getUsername());
					oaHetong.setUpdateTime(dtNow);
					oaHetong.setBillStatus("3"); //3表示首次审批通过
					oaHetongMapper.updateById(oaHetong);
				}
				//审批未完成，更新下一节点状态为待审批
				else {

					Stream<OaHetongShenpi> oaHetongShenpiStream1 = oaHetongShenpiList.stream()
							.filter(Sp -> Sp.getJiedianOrdinal().equals(finalOrdinal));

					oaHetongShenpiStream1.forEach(Sp -> {
						Sp.setSignResult("待审批");
						Sp.setSignYijian("");
						Sp.setSignTime(null);
						oaHetongShenpiMapper.updateById(Sp);

						//添加到待审批列表
						addApproval(Sp, oaHetong, resultColName,yijianColName, timeColName,billType,false);

					});


					oaHetong.setUpdateBy(sysUser.getUsername());
					oaHetong.setUpdateTime(dtNow);
					oaHetong.setShenpiOrdinal(finalOrdinal);
					oaHetongMapper.updateById(oaHetong);
				}

			}

		}
		//驳回，更新主表状态为驳回
		else {
			// 设置主表审批节点为子表第一个节点
			oaHetong.setShenpiOrdinal( oaHetongShenpiList.get(0).getJiedianOrdinal() );
			oaHetong.setBillStatus("0"); //0表示驳回

			oaHetong.setUpdateBy(sysUser.getUsername());
			oaHetong.setUpdateTime(dtNow);

			oaHetongMapper.updateById(oaHetong);

			for(OaHetongShenpi shenPi : oaHetongShenpiList){
				shenPi.setSignResult("");
				shenPi.setSignYijian("");
				shenPi.setSignTime(null);
				oaHetongShenpiMapper.updateById(shenPi);

			}

		}

	}

}
